package com.msf.common.utils;

import com.msf.common.annotation.tree.TreeChildrenAnnotation;
import com.msf.common.annotation.tree.TreeIdAnnotation;
import com.msf.common.annotation.tree.TreeParentIdAnnotation;
import org.apache.commons.lang3.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class ToTreeUtil {

    public static <T> void getTreeList(List<T> treeList, List<T> metaList, T temp) throws IllegalAccessException {
        for (T t : metaList) {
            String tempPid = (String) printFieldValue(t, TreeParentIdAnnotation.class);
            //组装菜单元信息
            if (temp == null && (oConvertUtils.isEmpty(tempPid) || oConvertUtils.isEqual("-1", tempPid))) {
                treeList.add(t);
                //组装菜单子对象
                getTreeList(treeList, metaList, t);
            } else if (temp != null && StringUtils.isNotBlank(tempPid) && !oConvertUtils.isEqual("-1", tempPid) && tempPid.equals(printFieldValue(temp, TreeIdAnnotation.class))) {
                List<T> children = (List<T>) printFieldValue(temp, TreeChildrenAnnotation.class);
                if (children == null) {
                    children = new ArrayList<T>();
                }
                children.add(t);
                setChildrenAnnotatedField(children, temp);
                getTreeList(treeList, metaList, t);
            }
        }
    }

    private static <T> Object printFieldValue(T t, Class<? extends Annotation> annotation) throws IllegalAccessException {
        Class<?> clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(annotation)) {
                field.setAccessible(true);
                return field.get(t);
            }
        }
        return null;
    }

    private static <T> void setChildrenAnnotatedField(List<T> children, T t) throws IllegalAccessException {
        Class<?> clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(TreeChildrenAnnotation.class)) {
                field.setAccessible(true);
                field.set(t, children);
            }
        }
    }

}
